Microsoft DirectX 8.1 (C++)

Override the Base Class Member Functions

When you determine which base class to use( see Determine Which Base Classes to Use), you write the header and define which member function to implement. You decide either to derive your filter class from the transform base classes (CTransformFilter or CTransInPlaceFilter), or from the more generic CBaseFilter filter class. In this section, you learn how to override the following member functions:

Override the Transform Member Function

The Transform member function in your derived class is called each time the IMemInputPin::Receive method on the input pin of the filter is called to transfer another sample. Place the code that performs the actual purpose of the filter in this member function, or in the functions called from here. Copy transform filters will likely have a private Copy member function associated with the transform code, while transform-in-place functions will simply modify the code in one buffer.

Override the CheckInputType Member Function

During the pin connection, the CheckMediaType member function of the input pin is called to determine whether the proposed media type is acceptable. The CTransformInputPin::CheckMediaType member function is implemented to call the CheckInputType member function of the derived filter class with the media type. You must implement this to accommodate the media types your filter can handle. The following code sample outlines part of the CGargle::CheckInputType member function, which rejects any media type but MEDIATYPE_Audio:

HRESULT CGargle::CheckInputType(const CMediaType *pmt) {    
    ...
    // Reject non-Audio type
    if (pmt->majortype != MEDIATYPE_Audio) {
        return E_INVALIDARG;
    }

Override the CheckTransform Member Function

Copy transform filters can transform the media type from the input pin to output pin. Therefore, if the output pin is connected (so its media type is known), when the CTransformInputPin::CheckMediaType member function is called during connection, the CheckTransform member function of the derived class is called to verify that the transform from the input type to the output type is valid. It is also called when CTransformOutputPin::CheckMediaType is called.

In the CTransInPlaceFilter class, this member function is implemented in the base class header file to simply return S_OK, because the functions from CTransformFilter that call this member function are overridden in CTransInPlaceFilter to call CheckInputType instead. This assumes that the media type doesn't change in a transform-in-place filter, as it might in a copy transform filter.

Override the DecideBufferSize Member Function

Copy transform filters might be required to set the properties of the allocator into which they are copying. This is likely if the downstream filter has provided a newly created allocator (that is, one that hasn't passed an allocator from farther downstream), or if the output pin is forced to create its own allocator. In this case, the pure virtual CBaseOutputPin::DecideBufferSize member function is called from the CBaseOutputPin::DecideAllocator member function, and the derived class fills in the requirements for the buffer by calling the IMemAllocator::SetProperties method on the allocator object to which it has a reference.

The CTransInPlaceFilter::DecideBufferSize method is never called, because the allocator of another filter is always in use. It is implemented in the base class header file to return E_UNEXPECTED.

Override the GetMediaType Member Function

Pins provide enumerators to enable other objects to determine the pin's media type. A pin provides the media type enumerator (the IEnumMediaTypes interface), which the pin base classes implement to call the GetMediaType member function in the pin class. In the copy transform filter classes, each pin's CTransformOutputPin::GetMediaType member function simply calls the virtual CTransformFilter::GetMediaType member function in the filter class. Your derived class must implement this member function to provide each supported media type in a list of media types.

In the transform-in-place classes, the enumerators form a transparent channel between the filters upstream and downstream from the transform filter. If the transform filter's input pin must perform an enumeration, it obtains an enumerator from the downstream filter's input pin. If the output pin must perform an enumeration, it obtains an enumerator from the upstream filter's output pin. One consequence of this is that transform-in-place filters can't connect to each other unless at least one of them is connected to something else, because neither of the transform-in-place filters can propose any media type for the connection.

Override Pin Member Functions

If you derived your filter class from the transform classes and want more than one input or output pin, you must override the pin class (for example, CTransformInputPin or CTransformOutputPin). If you override the pin class, you must also override the GetPin member function of CTransformFilter or CTransInPlaceFilter, so that you can create pin objects from your derived classes. If you override one of the pin classes (for example, CTransformInputPin) and override GetPin to create the pin object, you must also override GetPin to create the other pin object of the same base class (for example, CTransformOutputPin).

If you want more than one input or output pin, it is often simpler to derive your filter from CBaseFilter rather than from one of the transform classes.

Override the CBaseOutput::DecideAllocator Member Function

The base classes implement CBaseOutputPin::DecideAllocator to let the output pin automatically use the downstream pin's allocator. One of the most common alterations in the derived class is to force the use of an object's own allocator (or one from an upstream filter). In the DirectShow model, for example, a source filter pushes media samples onto the next filter and requires its own allocator. For example, if you write a transform-in-place filter and insert it between a source filter and a decompressor filter, the transform filter must present the source filter's allocator to the decompressor. Therefore, you must override the CBaseOutputPin::DecideAllocator member function.